package com.retlife.tvshow.usb;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest;
import android.os.IBinder;
import android.widget.Toast;

import com.retlife.tvshow.global.RunningContext;
import com.retlife.tvshow.serial_port.bike.model.BikeData;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

import androidx.annotation.Nullable;

public class UsbServer extends Service
{

    private UsbManager mUsbManager;
    private UsbDeviceConnection mUsbDeviceConnection;
    private UsbEndpoint mUsbEndpoint_in;
    private UsbEndpoint mUsbEndpoint_out;
    private ScheduledExecutorService scheduledExecutorService;
    private final Random random = new Random();

    @Override
    public void onCreate()
    {
        super.onCreate();
        scheduledExecutorService = new ScheduledThreadPoolExecutor(2, new ThreadFactory()
        {
            @Override
            public Thread newThread(Runnable r)
            {
                return new Thread(r, "UsbServer");
            }
        });
        mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
        for (String key : deviceList.keySet())
        {

        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        for (int i = 0; i < RunningContext.Companion.getMaxConnect(); i++){
            RunningContext.Companion.getBikeDataList().add(new BikeData());
        }
        scheduledExecutorService.scheduleAtFixedRate(new Runnable()
        {
            @Override
            public void run()
            {
                for (int i = 0; i < RunningContext.Companion.getMaxConnect(); i++)
                {
                    RunningContext.Companion.getBikeDataList().get(i).setSpeed(random.nextInt(11) + 80);
                    RunningContext.Companion.getBikeDataList().get(i).setTorqueAverage(random.nextInt(9) + 10);
                    RunningContext.Companion.getBikeDataList().get(i).setActive(random.nextBoolean());
                }
            }
        }, 1, 2000, TimeUnit.MILLISECONDS);

        return super.onStartCommand(intent, flags, startId);
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent)
    {
        return null;
    }

    public boolean connect(UsbDevice mUsbDevice)
    {
        if (mUsbDevice != null)
        {
            UsbInterface anInterface = mUsbDevice.getInterface(0);
            //连接usb设备
            mUsbDeviceConnection = mUsbManager.openDevice(mUsbDevice);
            if (mUsbDeviceConnection == null)
            {
                Toast.makeText(this, "mUsbDeviceConnection can't be null", Toast.LENGTH_SHORT).show();
                return false;
            }
            if (mUsbDeviceConnection.claimInterface(anInterface, true))
            {
                Toast.makeText(this, "找到USB接口", Toast.LENGTH_SHORT).show();
                int endpointCount = anInterface.getEndpointCount();
                for (int i = 0; i < endpointCount; i++)
                {
                    UsbEndpoint endpoint = anInterface.getEndpoint(i);
                    if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
                    {
                        if (UsbConstants.USB_DIR_IN == endpoint.getDirection())
                        {
                            //获取读数据通道
                            mUsbEndpoint_in = endpoint;
                        }
                        else
                        {
                            //获取写数据通道
                            mUsbEndpoint_out = endpoint;
                        }
                    }
                }
                return true;
            }
            else
            {
                mUsbDeviceConnection.close();//关闭连接
                Toast.makeText(this, "找不到USB接口", Toast.LENGTH_SHORT).show();
            }
        }
        else
        {
            Toast.makeText(this, "mUsbDevice can't be null", Toast.LENGTH_SHORT).show();
        }
        return false;
    }

    /**
     * 从usb通信设备中读取数据
     *
     * @return
     */
    public byte[] readData()
    {
        int inMax = mUsbEndpoint_in.getMaxPacketSize();
        byte[] bytes = new byte[inMax];
        ByteBuffer byteBuffer = ByteBuffer.allocate(inMax);
        UsbRequest usbRequest = new UsbRequest();
        usbRequest.initialize(mUsbDeviceConnection, mUsbEndpoint_in);
        usbRequest.queue(byteBuffer, inMax);
        if (mUsbDeviceConnection.requestWait() == usbRequest)
        {
            bytes = byteBuffer.array();
        }
        return bytes;
    }

    /**
     * 将数据写入到usb设备中
     *
     * @param bytes
     */
    public void sendData(byte[] bytes)
    {
        if (mUsbDeviceConnection == null)
        {
            Toast.makeText(this, "mUsbDeviceConnection can't be null", Toast.LENGTH_SHORT).show();
            return;
        }
        if (mUsbEndpoint_out == null)
        {
            Toast.makeText(this, "mUsbEndpoint_out can't be null", Toast.LENGTH_SHORT).show();
            return;
        }

        int i = mUsbDeviceConnection.bulkTransfer(mUsbEndpoint_out, bytes, bytes.length, 1000);
        if (i < 0)
        {
            Toast.makeText(this, "failure to write", Toast.LENGTH_SHORT).show();
        }
        else
        {
            Toast.makeText(this, "success to write", Toast.LENGTH_SHORT).show();
        }
    }

}
